#include <GL/glew.h>
#include "KDInter.h"
#include "../mray0.3/vec3.h"

const uint mgl::KDInter::g_iBufferCube [] = {
	0,1,2,
	2,1,5,
	5,1,7,
	1,4,7,
	6,2,7,
	2,5,7,
	0,2,6,
	0,6,3,
	1,0,3,
	1,3,4,
	4,3,6,
	4,6,7,
};

const uint mgl::KDInter::g_iBufferWire [] = {
	0,1,
	0,2,
	0,3,
	1,5,
	5,2,
	2,6,
	6,3,
	3,4,
	4,1,
	7,4,
	7,5,
	7,6,
};


uint mgl::KDInter::g_iBufferIdCube = GL_INVALID_VALUE;
uint mgl::KDInter::g_iBufferIdWire = GL_INVALID_VALUE;

mgl::KDInter::KDInter(const std::array<float, 6>& arr)
{
	//min point
	vertex(0, X) = arr[0];
	vertex(2, X) = arr[0];
	vertex(3, X) = arr[0];
	vertex(6, X) = arr[0];

	vertex(0, Y) = arr[1];
	vertex(1, Y) = arr[1];
	vertex(2, Y) = arr[1];
	vertex(5, Y) = arr[1];

	vertex(0, Z) = arr[2];
	vertex(1, Z) = arr[2];
	vertex(3, Z) = arr[2];
	vertex(4, Z) = arr[2];
	//max point
	vertex(1, X) = arr[3];
	vertex(4, X) = arr[3];
	vertex(5, X) = arr[3];
	vertex(7, X) = arr[3];

	vertex(3, Y) = arr[4];
	vertex(4, Y) = arr[4];
	vertex(6, Y) = arr[4];
	vertex(7, Y) = arr[4];

	vertex(2, Z) = arr[5];
	vertex(5, Z) = arr[5];
	vertex(6, Z) = arr[5];
	vertex(7, Z) = arr[5];

	m_type = Cube;
}

void mgl::KDInter::createBuffer()
{
	//index cube
	if(g_iBufferIdCube == GL_INVALID_VALUE){
		glGenBuffers(1, &g_iBufferIdCube);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_iBufferIdCube);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_iBufferCube), g_iBufferCube, GL_STATIC_DRAW);
	}

	//index wire
	if(g_iBufferIdWire == GL_INVALID_VALUE){
		glGenBuffers(1, &g_iBufferIdWire);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_iBufferIdWire);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_iBufferWire), g_iBufferWire, GL_STATIC_DRAW);
	}

	//vertex
	glGenBuffers(1, &m_vBufferId);
	glBindBuffer(GL_ARRAY_BUFFER, m_vBufferId);
	glBufferData(GL_ARRAY_BUFFER, sizeof(m_vBuffer), m_vBuffer, GL_STATIC_DRAW);
}

void mgl::KDInter::releaseBuffer()
{
	if(g_iBufferIdCube != GL_INVALID_VALUE){
		glDeleteBuffers(1, &g_iBufferIdCube);
		g_iBufferIdCube = GL_INVALID_VALUE;
	}

	if(g_iBufferIdWire != GL_INVALID_VALUE){
		glDeleteBuffers(1, &g_iBufferIdWire);
		g_iBufferIdWire = GL_INVALID_VALUE;
	}

	glDeleteBuffers(1, &m_vBufferId);
}

void mgl::KDInter::draw()const
{
	switch(m_type){
	case Cube:
		drawCube();
		break;
	case Wire:
		drawWire();
		break;
	}
}

void mgl::KDInter::testData()
{
	const static float test [] = {
		0,0,0,
		1,0,0,
		0,0,1,
		0,1,0,
		1,1,0,
		1,0,1,
		0,1,1,
		1,1,1,
	};
	std::memcpy(m_vBuffer, test, sizeof(test));
}

void mgl::KDInter::drawCube()const
{
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);

	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, m_vBufferId);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_iBufferIdCube);
	glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, nullptr);

	glDisableVertexAttribArray(0);

	glEnable(GL_CULL_FACE);
//	glEnable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);
}

void mgl::KDInter::drawWire()const
{
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, m_vBufferId);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_iBufferIdWire);
	glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, nullptr);

	glDisableVertexAttribArray(0);
}
